1   /************************************************************
2   *                     Copyright                            *
3   * Portions of this software are Copyright (c) 1993 - 2002, *
4   * Chad Z. Hower (Kudzu) and the Indy Pit Crew              *
5   *  - http://www.nevrona.com/Indy/                          *
6   ************************************************************/
7   package org.indy;
8   
9   import java.util.Collection;
10  import java.util.HashSet;
11  import java.util.Iterator;
12  import java.util.StringTokenizer;
13  
14  import org.indy.util.StringList;
15  
16  
17  /***
18   *  Provides the basis for {@link TCPServer} command handling.
19   *
20   *@version   1.0
21   *@author    OTG
22   */
23  public class CommandHandler {
24    private char cmdDelimiter;
25    private boolean disconnect;
26    private boolean enabled;
27    private String command;
28    private char paramDelimiter;
29    private boolean parseParams;
30    private int replyExceptionCode;
31    private RFCReply replyNormal;
32    private StringList response = new StringList();
33    private int tag;
34    private final CommandHandlers handlersList;
35    private Collection commandListeners = new HashSet();
36  
37    /***
38   *  Constructs a new instance. Takes a
39   *  reference to this handler's containing {@link CommandHandlers}
40   *  collection.
41   *
42   * @param  collection  The <code>CommandHandlers</code> collection that contains this handler.
43   */
44    public CommandHandler(CommandHandlers collection) {
45      handlersList = collection;
46    }
47  
48    /***
49   *  Sets the command delimiter for this handler object.
50   *
51   *@param  cmdDelimiter  The new delimiter value
52   */
53    public void setCmdDelimiter(char cmdDelimiter) {
54      this.cmdDelimiter = cmdDelimiter;
55    }
56  
57    /***
58   *  Sets whether this handler should disconnect from the client when it has finished.
59   *
60   *@param  disconnect  The new disconnect value
61   */
62    public void setDisconnect(boolean disconnect) {
63      this.disconnect = disconnect;
64    }
65  
66    /***
67   *  Enables / disables this handler.
68   *
69   *@param  enabled  <code>true</code> to enable the handler, <code>false</code> to disable.
70   */
71    public void setEnabled(boolean enabled) {
72      this.enabled = enabled;
73    }
74  
75    /***
76   *  Sets command string that this handler is associated with.
77   *
78   *@param  command  The new command value
79   */
80    public void setCommand(String command) {
81      this.command = command;
82    }
83  
84    /***
85   *  Sets the parameter delimiter for this handler.
86   *
87   *@param  paramDelimiter  The new parameter delimiter.
88   */
89    public void setParamDelimiter(char paramDelimiter) {
90      this.paramDelimiter = paramDelimiter;
91    }
92  
93    /***
94   *  Sets whether this handler should attempt to parse the parameters sent to it.
95   *
96   *@param  parseParams  <code>true</code> to enable parsing, <code>false</code> to disable.
97   */
98    public void setParseParams(boolean parseParams) {
99      this.parseParams = parseParams;
100   }
101 
102   /***
103  *  Sets the numerical code for this handler to use if an exception is encountered during processing (e.g. 500 for an http server).
104  *
105  *@param  replyExceptionCode  The numerical reply for exception conditions
106  */
107   public void setReplyExceptionCode(int replyExceptionCode) {
108     this.replyExceptionCode = replyExceptionCode;
109   }
110 
111   /***
112  *  Sets the standard {@link org.indy.RFCReply} object to use as a response to this command
113  *
114  *@param  replyNormal  The new replyNormal value
115  */
116   public void setReplyNormal(RFCReply replyNormal) {
117     this.replyNormal = replyNormal;
118   }
119 
120   /***
121  *  Sets the {@link org.indy.util.StringList} that form the textual reponse for this command handler.
122  *
123  *@param  response  The new response value
124  */
125   public void setResponse(StringList response) {
126     /***
127  *@todo    Use copy constructor?
128  */
129     this.response.copy(response);
130   }
131 
132   /***
133  *  Sets the tag attribute of the <code>CommandHandler</code> object
134  *
135  *@param  tag  The new tag value
136  */
137   public void setTag(int tag) {
138     this.tag = tag;
139   }
140 
141   /***
142  *  Returns the containing collection of this command handler.
143  *
144  *@return    The commandHandlers value
145  */
146   public CommandHandlers getCommandHandlers() {
147     return handlersList;
148   }
149 
150   /***
151  *  Gets the command delimiter for this command handler
152  *
153  *@return    The cmdDelimiter value
154  */
155   public char getCmdDelimiter() {
156     return cmdDelimiter;
157   }
158 
159   /***
160  *  Gets the disconnect attribute of the <code>CommandHandler</code> object
161  *
162  *@return    The disconnect value
163  */
164   public boolean isDisconnected() {
165     return disconnect;
166   }
167 
168   /***
169  *  Gets the enabled attribute of the IdCommandHandler object
170  *
171  *@return    The enabled value
172  */
173   public boolean isEnabled() {
174     return enabled;
175   }
176 
177   /***
178  *  Gets the command attribute of the IdCommandHandler object
179  *
180  *@return    The command value
181  */
182   public String getCommand() {
183     return command;
184   }
185 
186   /***
187  *  Gets the paramDelimiter attribute of the IdCommandHandler object
188  *
189  *@return    The paramDelimiter value
190  */
191   public char getParamDelimiter() {
192     return paramDelimiter;
193   }
194 
195   /***
196  *  Gets the parseParams attribute of the <code>CommandHandler</code> object
197  *
198  *@return    The parseParams value
199  */
200   public boolean isParseParams() {
201     return parseParams;
202   }
203 
204   /***
205  *  Gets the replyExceptionCode attribute of the <code>CommandHandler</code> object
206  *
207  *@return    The replyExceptionCode value
208  */
209   public int getReplyExceptionCode() {
210     return replyExceptionCode;
211   }
212 
213   /***
214  *  Gets the replyNormal attribute of the <code>CommandHandler</code> object
215  *
216  *@return    The replyNormal value
217  */
218   public RFCReply getReplyNormal() {
219     return replyNormal;
220   }
221 
222   /***
223  *  Gets the response attribute of the CommandHandler object
224  *
225  *@return    The response value
226  */
227   public StringList getResponse() {
228     return response;
229   }
230 
231   /***
232  *  Gets the tag attribute of the CommandHandler object
233  *
234  *@return    The tag value
235  */
236   public int getTag() {
237     return tag;
238   }
239 
240   /***
241  *  Calls all {@link CommandListener}'s {@link CommandListener#onCommand()} method.
242  *
243  *@param  command       The {@link IdCommand} object to pass.
244  *@throws  IdException  If an exception is thrown by the IdCommandListener
245  */
246   protected void doCommand(CommandEvent command) throws IndyException {
247     synchronized (commandListeners) {
248       Iterator i = commandListeners.iterator();
249 
250       while (i.hasNext()) {
251         ((CommandHandlerListener) i.next()).onCommand(command);
252       }
253     }
254   }
255 
256   /***
257  *  Parses a command, notifies any {@link IdCommandListener} instances
258  *  that are registered, and returns <code>true</code> if the
259  *  command was recognised.
260  *
261  *@param  data          The command to parse.
262  *@param  thread        The thread that received the command.
263  *@return               <code>true</code> if the command was recognized and parsed sucessfully, <code>false</code> otherwise.
264  *@throws  IdException  If an exeception is encountered whilst processing the command.
265  */
266   final boolean check(String data, PeerThread thread) throws IndyException {
267     boolean result = command.equalsIgnoreCase(data);
268     String unparsedParams = null;
269 
270     if (!result && (data.length() > command.length())) {
271       if (cmdDelimiter != '\u0000') {
272         result = data.substring(0, command.length())
273                      .equalsIgnoreCase(command + cmdDelimiter);
274         unparsedParams = data.substring(command.length() + 1);
275       }
276       else {
277         result = data.substring(0, command.length() - 1)
278                      .equalsIgnoreCase(command);
279         unparsedParams = data.substring(command.length());
280       }
281     }
282 
283     if (result) {
284       CommandEvent command = new CommandEvent();
285 
286       try {
287         command.setCommandHandler(this);
288         command.setRawLine(data);
289         command.setThread(thread);
290         command.setUnparsedParams(unparsedParams);
291         command.setPerformReply(true);
292         command.setReply(this.replyNormal);
293 
294         if (parseParams) {
295           StringTokenizer tok = new StringTokenizer(data, 
296                                                     String.valueOf(
297                                                         paramDelimiter));
298           StringList params = command.getParams();
299 
300           while (tok.hasMoreTokens()) {
301             params.add(tok.nextToken());
302           }
303 
304 
305           //end while
306           command.setUnparsedParams("");
307         }
308         else {
309           command.getParams().add(unparsedParams);
310         }
311 
312         //if parse params
313         while (true) {
314           try {
315             doCommand(command);
316           }
317            catch (IndyException ide) {
318             if (command.getPerformReply()) {
319               if (replyExceptionCode > 0) {
320                 command.getReply()
321                        .setReply(replyExceptionCode, ide.getMessage());
322                 command.sendReply();
323               }
324               else {
325                 throw ide;
326               }
327 
328               //if reply exception code > 0
329               break;
330             }
331 
332             //if command.performReply
333             else {
334               throw ide;
335             }
336 
337             //!command.performReply
338           }
339 
340           //catch
341           if (command.getPerformReply()) {
342             command.sendReply();
343           }
344 
345           if (command.getResponse().size() > 0) {
346             thread.getConnection().writeRFCStrings(command.getResponse());
347           }
348           else if (this.response.size() > 0) {
349             thread.getConnection().writeRFCStrings(this.response);
350           }
351 
352           break;
353         }
354 
355         //while
356       }
357        finally {
358         if (disconnect) {
359           command = null;
360           thread.getConnection().disconnect();
361         }
362       }
363     }
364 
365     //if
366     return result;
367   }
368 
369   /***
370  *  Unregisters an {@link IdCommandListener} instance.
371  *
372  *@param  l  The listener to remove.
373  */
374   public synchronized void removeCommandListener(CommandHandlerListener l) {
375     commandListeners.remove(l);
376   }
377 
378   /***
379  *  Registers an {@link IdCommandListener} instance to be informed of
380  *  events from this handler.
381  *
382  *@param  l  The listener to add.
383  */
384   public synchronized void addCommandListener(CommandHandlerListener l) {
385     commandListeners.add(l);
386   }
387 }
This page was automatically generated by Maven